local famBags = LibStub('AceAddon-3.0'):GetAddon('famBags')
famBags.Sorting = {}

-- :::::::::::: LOCALS ::::::::::::: -------------------------------------------------------------------------

-- :::::::::::: famBags.Classification ::::::::::::: -------------------------------------------------------------------------
function famBags.Sorting:Sort(b1, b2)
   if not b2 then return true end
   local db = famBags.db.profile.layout.order
   local a, b = b1.info, b2.info
   local found
   for i,order in ipairs(db.customs) do
      found = self[order.order](a, b, order.sorting)
      if found ~= nil then return found end
   end
   -- If no criteria decides then ascending bag/slot decides
   if a.bag ~= b.bag then
      return a.bag < b.bag
   else
      return a.slot < b.slot
   end
end

famBags.Sorting['ORDER_EMPTY'] = function(a, b, sorting)
   if not(a.id and b.id) and (a.id or b.id) then
      return ((sorting == 'ORDER_GO_FIRST' and b.id) or (sorting == 'ORDER_GO_LAST' and a.id)) or false
   end
   return nil
end

famBags.Sorting['ORDER_ITEM_ID'] = function(a, b, sorting)
   if a.id and b.id and a.id ~= b.id then
      return ((sorting == 'ORDER_ASCENDING' and b.id > a.id) or (sorting == 'ORDER_DESCENDING' and a.id > b.id)) or false
   end
   return nil
end

famBags.Sorting['ORDER_QUALITY'] = function(a, b, sorting)
   if a.quality and b.quality then
      if a.quality ~= b.quality then
         return ((sorting == 'ORDER_ASCENDING' and b.quality > a.quality) or (sorting == 'ORDER_DESCENDING' and a.quality > b.quality)) or false
      else
         return nil
      end
   elseif a.quality or b.quality then
      return a.quality or false
   end
   return nil
end

famBags.Sorting['ORDER_QUEST_ITEM'] = function(a, b, sorting)
   if not(a.isQuestItem and b.isQuestItem) and (a.isQuestItem or b.isQuestItem) then
      return ((sorting == 'ORDER_GO_FIRST' and not b.isQuestItem) or (sorting == 'ORDER_GO_LAST' and not a.isQuestItem)) or false
   end
   return nil
end

famBags.Sorting['ORDER_TYPE'] = function(a, b, sorting)
   if a.type and b.type then
      if a.type ~= b.type then
         return ((sorting == 'ORDER_ASCENDING' and b.type > a.type) or (sorting == 'ORDER_DESCENDING' and a.type > b.type)) or false
      else
         return nil
      end
   elseif a.type or b.type then
      return a.type or false
   end
   return nil
end

famBags.Sorting['ORDER_SUBTYPE'] = function(a, b, sorting)
   if a.subType and b.subType then
      if a.subType ~= b.subType then
         return ((sorting == 'ORDER_ASCENDING' and b.subType > a.subType) or (sorting == 'ORDER_DESCENDING' and a.subType > b.subType)) or false
      else
         return nil
      end
   elseif a.subType or b.subType then
      return a.subType or false
   end
   return nil
end

famBags.Sorting['ORDER_ILEVEL'] = function(a, b, sorting)
   if a.iLvl and b.iLvl then
      if a.iLvl ~= b.iLvl then
         return ((sorting == 'ORDER_ASCENDING' and b.iLvl > a.iLvl) or (sorting == 'ORDER_DESCENDING' and a.iLvl > b.iLvl)) or false
      else
         return nil
      end
   elseif a.iLvl or b.iLvl then
      return a.iLvl or false
   end
   return nil
end

famBags.Sorting['ORDER_RLEVEL'] = function(a, b, sorting)
   if a.minLvl and b.minLvl then
      if a.minLvl ~= b.minLvl then
         return ((sorting == 'ORDER_ASCENDING' and b.minLvl > a.minLvl) or (sorting == 'ORDER_DESCENDING' and a.minLvl > b.minLvl)) or false
      else
         return nil
      end
   elseif a.minLvl or b.minLvl then
      return a.minLvl or false
   end
   return nil
end

famBags.Sorting['ORDER_STACK_SIZE'] = function(a, b, sorting)
   if a.stack and b.stack then
      if a.stack ~= b.stack then
         return ((sorting == 'ORDER_ASCENDING' and b.stack > a.stack) or (sorting == 'ORDER_DESCENDING' and a.stack > b.stack)) or false
      else
         return nil
      end
   elseif a.stack or b.stack then
      return ((sorting == 'ORDER_ASCENDING' and b.stack) or (sorting == 'ORDER_DESCENDING' and a.stack)) or false
   end
   return nil
end

famBags.Sorting['ORDER_COUNT'] = function(a, b, sorting)
   if a.count and b.count then
      if a.count ~= b.count then
         return ((sorting == 'ORDER_ASCENDING' and b.count > a.count) or (sorting == 'ORDER_DESCENDING' and a.count > b.count)) or false
      else
         return nil
      end
   elseif a.count or b.count then
      return ((sorting == 'ORDER_ASCENDING' and b.count) or (sorting == 'ORDER_DESCENDING' and a.count)) or false
   end
   return nil
end

famBags.Sorting['ORDER_EQUIPSLOT'] = function(a, b, sorting)
   local slots = famBags.Criterias[FAMBAGSCRITERIA_EQUIPSLOT].strKeyedOptions
   if a.equipLoc and b.equipLoc then
      if a.equipLoc ~= b.equipLoc then
         local a1, b1 = _G[a.equipLoc], _G[b.equipLoc]
         if not (a1 and b1) then
            if a1 or b1 then
               return ((sorting == 'ORDER_ASCENDING' and a1) or (sorting == 'ORDER_DESCENDING' and b1)) or false
            else
               return nil
            end
         end
         if slots[a1] and slots[b1] then
            return ((sorting == 'ORDER_ASCENDING' and slots[b1] > slots[a1]) or (sorting == 'ORDER_DESCENDING' and slots[a1] > slots[b1])) or false
         elseif slots[a1] or slots[b1] then
            return ((sorting == 'ORDER_ASCENDING' and slots[a1]) or (sorting == 'ORDER_DESCENDING' and slots[b1])) or false
         else
            return nil
         end
      else
         return nil
      end
   elseif a.equipLoc or b.equipLoc then
      return ((sorting == 'ORDER_ASCENDING' and a.equipLoc) or (sorting == 'ORDER_DESCENDING' and b.equipLoc)) or false
   end
   return nil
end

